package com.lds.sign_sdk.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.MethodHandles;
import java.util.regex.Pattern;

/**
 * @Date 2022/7/29
 * @Time 16:00
 * @Author liudongs
 * @E-mail liudongs@aliyun.com
 * @Version 1.0.0
 * @Description
 **/
public class DesensitizeUtil {
    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    public static final String PHONE_REG = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$";
    public static final String EMAIL_REG = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$";
    public static final String BANK_CARD_NUMBER = "^\\d{16}|\\d{19}$";
    public static final String ID_CARD = "^\\d{15}|(\\d{17}[0-9,x,X])$";

    public DesensitizeUtil() {
    }

    public static String replaceSecretInfo(String info, String fillValue) {
        if (info.isEmpty()) {
            return "";
        } else {
            int infoLength = info.length();
            String result;
            if (infoLength == 1) {
                result = "*";
            } else if (infoLength == 2) {
                result = info.substring(0, 1) + "*";
            } else {
                double tempNum = (double)infoLength / 3.0D;
                int num1 = (int)Math.floor(tempNum);
                int num2 = (int)Math.ceil(tempNum);
                int num3 = infoLength - num1 - num2;
                String star = "";

                for(int i = 0; i < num2; ++i) {
                    star = star.concat(fillValue);
                }

                String regex = "(.{" + num1 + "})(.{" + num2 + "})(.{" + num3 + "})";
                String replacement = "$1" + star + "$3";
                result = info.replaceAll(regex, replacement);
            }

            return result;
        }
    }

    public static String encryptBankAcct(String bankAcct, String replacement) {
        return bankAcct == null ? "" : replaceBetween(bankAcct, 6, bankAcct.length() - 4, replacement);
    }

    public static String encryptIdCard(String idCard, String replacement) {
        return idCard == null ? "" : replaceBetween(idCard, 6, idCard.length() - 4, replacement);
    }

    public static String encryptEmail(String email, String replacement) {
        if (email != null && Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", email)) {
            StringBuilder sb = new StringBuilder(email);
            int at_position = sb.indexOf("@");
            if (at_position > 2) {
                sb.replace(2, at_position, repeat(replacement, at_position - 2));
            }

            int period_position = sb.lastIndexOf(".");
            sb.replace(at_position + 1, period_position, repeat(replacement, period_position - at_position - 1));
            return sb.toString();
        } else {
            return "";
        }
    }

    public static String encryptPhoneNo(String phoneNo, String replacement) {
        return phoneNo == null ? "" : replaceBetween(phoneNo, 3, phoneNo.length() - 4, replacement);
    }

    public static String encryptSensitiveInfo(String sourceStr, String replacement) {
        if (sourceStr == null) {
            return "";
        } else if (Pattern.matches("^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$", sourceStr)) {
            return encryptPhoneNo(sourceStr, replacement);
        } else if (Pattern.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", sourceStr)) {
            return encryptEmail(sourceStr, replacement);
        } else if (Pattern.matches("^\\d{16}|\\d{19}$", sourceStr)) {
            return encryptBankAcct(sourceStr, replacement);
        } else {
            return Pattern.matches("^\\d{15}|(\\d{17}[0-9,x,X])$", sourceStr) ? encryptIdCard(sourceStr, replacement) : replaceSecretInfo(sourceStr, replacement);
        }
    }

    private static String replaceBetween(String sourceStr, int begin, int end, String replacement) {
        if (sourceStr == null) {
            return "";
        } else {
            if (replacement == null) {
                replacement = "*";
            }

            int replaceLength = end - begin;
            if (replacement.length() > 0 && replaceLength > 0) {
                StringBuilder sb = new StringBuilder(sourceStr);
                sb.replace(begin, end, repeat(replacement, replaceLength));
                return sb.toString();
            } else {
                return sourceStr;
            }
        }
    }

    private static String repeat(String value, int count) {
        String result = "";
        if (count > 0 && value != null && !"".equals(value)) {
            for(int i = 0; i < count; ++i) {
                result = result.concat(value);
            }
        }

        return result;
    }
}
